#pragma once

#include <ShlObj.h>
#include <algorithm>

#include "version.h"
#include "AEUpdateable.hpp"
#include "AETaskManager.hpp"
#include "AESettingsManager.hpp"
#include "AERenderingEngine.hpp"
#include "AEStateManager.hpp"
#include "AEScriptEngine.hpp"
#include "AEGUISystem.hpp"
#include "AEInputManager.hpp"
#include "AELogManager.hpp"
#include "AEAudioManager.hpp"

BEGIN_ARETE_NAMESPACE(core)
class AEApplication
{
public:
	AEApplication(void);
	~AEApplication(void);

	bool initialize(char**,int);

	void run(void);

	void registerForUpdates(components::AEUpdateable*,float);
	void deregisterForUpdates(components::AEUpdateable*);

private:
	string findUserDirectory(void);
	void parseArguements(char**,int);
	void initializeAudio( void );
	void registerScriptGlobals( void );

	std::shared_ptr<rendering::AERenderingEngine> m_renderingengine;
	std::shared_ptr<AEStateManager> m_statemanager;
	std::shared_ptr<io::AESettingsManager> m_settings;
	std::shared_ptr<thread::AETaskManager> m_taskmanager;
	std::shared_ptr<scripting::AEScriptEngine> m_scriptengine;
	std::shared_ptr<io::AELogManager> m_logmanager;
	std::shared_ptr<gui::AEGUISystem> m_guiengine;
	std::shared_ptr<input::AEInputManager> m_inputmanager;
	std::shared_ptr<audio::AEAudioManager> m_audiomanager;

	Ogre::map<components::AEUpdateable*,std::pair<long,float>>::type m_updating;

	bool m_exiting;
};
END_ARETE_NAMESPACE